import argparse, os, re, subprocess, shutil
from pathlib import Path
import yaml

WS = Path(__file__).resolve().parents[1]
SRC = WS / "src"
DEFAULTS = WS / ".colcon" / "defaults.yaml"

ALL_PACKAGES = ["ts-common", "ts-comms", "ts-mock"]  # 🔒 写死的包名列表

def parse_args():
    p = argparse.ArgumentParser(prog="conan install")
    p.add_argument(
        "-p",
        "--package",
        choices=ALL_PACKAGES,
        nargs="+",
        help=f"要处理的包名（可多个），默认全部: {', '.join(ALL_PACKAGES)}"
    )
    p.add_argument(
        "-t",
        "--cmake_type",
        choices=["Debug","Release","RelWithDebInfo","MinSizeRel"],
        help="CMAKE_BUILD_TYPE（默认读取 .colcon/defaults.yaml）"
    )
    return p.parse_args()



def detect_build_type() -> str:
    if DEFAULTS.exists():
        data = yaml.safe_load(DEFAULTS.read_text())
        # defaults.yaml 的结构一般是：
        # build:
        #   cmake-args:
        #     - -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake
        #     - -DCMAKE_BUILD_TYPE=RelWithDebInfo
        if "build" in data and "cmake-args" in data["build"]:
            for arg in data["build"]["cmake-args"]:
                if isinstance(arg, str) and "CMAKE_BUILD_TYPE" in arg:
                    # 可能是 "-DCMAKE_BUILD_TYPE=Debug"
                    if "=" in arg:
                        return arg.split("=")[-1].strip()
                    # 也可能是 ["-DCMAKE_BUILD_TYPE", "Debug"] 两段式
                elif isinstance(arg, list) and len(arg) == 2 and "CMAKE_BUILD_TYPE" in arg[0]:
                    return arg[1]
    return "RelWithDebInfo"

def run(cmd: list[str]):
    print(" $", " ".join(cmd))
    subprocess.check_call(cmd)


def safe_symlink(src: Path, dst: Path):
    dst.parent.mkdir(parents=True, exist_ok=True)
    try:
        if dst.exists() or dst.is_symlink():
            dst.unlink()
        rel = os.path.relpath(src, dst.parent)
        os.symlink(rel, dst)
        print(f" 🔗 link: {dst} -> {rel}")
    except OSError:
        shutil.copy2(src, dst)
        print(f" 📄 copy: {src} -> {dst}")

def main():
    # parse args
    args = parse_args()

    build_type = args.cmake_type or detect_build_type()
    print(f"=== Build Type: {build_type}")
    
    target = args.package or ALL_PACKAGES
    print(f"=== Target Packages: {', '.join(target)}")


    for name in target:
        conan = SRC / name / "conan"
        out = conan / build_type
        out.mkdir(parents=True, exist_ok=True)
        print(f">>> conan install: {conan}")
        run([
            "conan","install", str(conan),
            "-of", str(out),
            "-s", f"build_type={build_type}",
            "--build=missing",
        ])

    # for name in target:
    #     tc_src = CONAN_OUT / name / "build" / build_type / "generators" / "conan_toolchain.cmake"
    #     tc_dst = BUILD / name / "conan_toolchain.cmake"
    #     if not tc_src.exists():
    #         print(f" ⚠️  {name}: 缺少 {tc_src} (确认 conanfile 里有 [generators])")
    #         continue
    #     safe_symlink(tc_src, tc_dst)

    print("✅ 完成，可以 colcon build 了")






if __name__ == "__main__":
    main()
